package com.thon.controller.rest;

import java.util.HashMap;
import java.util.Map;

import javax.validation.Valid;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.common.collect.Maps;
import com.thon.commons.utils.OrderNoGenerator;
import com.thon.commons.utils.ApplicationEnum.UserStatus;
import com.thon.dao.util.Page;
import com.thon.entity.project.Product;
import com.thon.entity.project.Project;
import com.thon.entity.project.ProjectSupport;
import com.thon.entity.project.ProjectUnsupport;
import com.thon.entity.user.FundDetail;
import com.thon.entity.user.Institution;
import com.thon.entity.user.Present;
import com.thon.entity.user.SendTo;
import com.thon.entity.user.User;
import com.thon.service.project.ProductService;
import com.thon.service.project.ProjectService;
import com.thon.service.project.ProjectSupportService;
import com.thon.service.project.ProjectUnsupportService;
import com.thon.service.user.FundDetailService;
import com.thon.service.user.PresentService;
import com.thon.service.user.SendToService;
import com.thon.service.user.UserService;

/**
 * @file ProjectSupportRestController.java
 * @author Zemo
 * @mail zemochen@gmail.com
 * @data 2013年11月18日 下午7:12:41
 * @description: TODO
 */
@Controller
@RequestMapping(value = "/api/project")
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ProjectSupportRestController {

	private static final Log log = LogFactory.getLog(ProjectSupportRestController.class);

	@Autowired
	private UserService userService;
	@Autowired
	private ProductService productService;
	@Autowired
	private ProjectService projectService;
	@Autowired
	private ProjectSupportService projectSupportService;
	@Autowired
	private ProjectUnsupportService projectUnsupportService;
	@Autowired
	private FundDetailService fundDetailService;
	@Autowired
	private PresentService presentService;
	@Autowired
	private SendToService sendToService;

	// 根据projectSupport id 获取支持详情
	@RequestMapping(value = "/support", method = RequestMethod.GET)
	public ResponseEntity<HttpEntity> getProjectSupportDetail(
			@RequestParam("id") int id, Model model) {

		ProjectSupport projectSupport = projectSupportService.getProjectSupport(id);
		//String institutionName = projectSupport.getProject().getInstitution().getName();
		//model.addAttribute("institutionName", institutionName);
		model.addAttribute("projectSupport", projectSupport);
		return new ResponseEntity(model, HttpStatus.OK);
	}

	// 验证余额
	// 根据项目id添加支持并更新project 表中的支持数,更新筹款数,更新用户积善值
	// 购买商品
	@RequestMapping(value = "/support/add", method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public ResponseEntity<HttpEntity> supprotPorject(
			@Valid @RequestBody ProjectSupport projectSupport) {
		Map map = new HashMap();
		User user = new User();
		Institution institution = new Institution();
		Project project = new Project();
		Product product = new Product();
		FundDetail fundDetail = new FundDetail();
		Integer projectId = projectSupport.getProject().getId();
		project = projectService.getProject(-1, projectId);
		institution = project.getInstitution();
		user = userService.getUser(projectSupport.getUser().getId());
		product = productService.getProduct(projectSupport.getProduct().getId());
		int totle_fee = product.getPrice()*projectSupport.getProductAmount();
		FundDetail fundDetial = fundDetailService.getFundDetail(user.getId());
		if(fundDetial!=null)
		{	totle_fee +=fundDetial.getAmount();			
		}
		if (user.getFund() < totle_fee) {
			log.debug("user's fund is:" + user.getFund());
			map.put("error", "Lack of Funds!");
			map.put("product", product);
			return new ResponseEntity(map, HttpStatus.BAD_REQUEST);
		} 	/*else if (product.getRemaining() == 0||product.getRemaining() < projectSupport.getProductAmount()) {
			log.debug("Remaining deficiencies!");
			map.put("error", "Remaining deficiencies ");
			map.put("product", product);
			return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);*/
		if (project.getStatus()!=5) {
			log.debug("Project's status is fail!");
			map.put("error", "Project's status is fail ");
			map.put("product", product);
			return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
		}
			int count =0;
			int sum = 0;
			int userId = projectSupport.getUser().getId();
			int productId = projectSupport.getProduct().getId();
			int historyCount = projectSupportService.sumProductAmount(projectId, userId,productId).intValue();
			count =  projectSupport.getProductAmount(); //本次购买商品数量
			int sumcount = count + historyCount;    //加上本次一共购买商品数量
			int limit = product.getCaps()==null? 0:product.getCaps(); //个人服务商购买限额
			String role =null;
					//userService.getUser(userId).getRoles();
			String permissions = product.getPermissions();
			//判断是否有权限，及购买数量是否大于上限
			if(!permissions.equals("yes")){
				map.put("error", "No buy permissions");
				return new ResponseEntity(map,HttpStatus.FORBIDDEN);
			}
			//关闭数量限制
			/*if ( role.equals("user")&&sumcount > limit) {
				map.put("error", "Beyond the purchase limit");
				return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
			}*/
			sum = product.getPrice() * count;
			/**
			 * 101资助成功，正在发送回报 102资助成功，成功发送回报 201资助失败，正在退款 202资助失败，已退款
			 */
			String no = OrderNoGenerator.generator("NO");
			product.setAmmount(count+product.getAmmount());
			productService.update(product);
			projectSupport.setStatus(101);
			projectSupport.setFundCode(no);
			projectSupport.setIsBuy(0);
			projectSupportService.add(projectSupport);

			/*
			 * 1充值 0支出
			 */
			fundDetail.setActionType(0);
			fundDetail.setAmount(sum);
			fundDetail.setProject(project);
			fundDetail.setProduct(product);
			fundDetail.setUser(user);
			fundDetail.setTradeNo(no);
			fundDetail.setRemainingSum(user.getFund() - sum);
			fundDetailService.addFundDetail(fundDetail);
			user.setFund(user.getFund() - sum);
			userService.updateUser(user);
			
			//更新卖家的余额
			
			User seller =institution.getUser();	
			FundDetail sellFundDetail = new FundDetail();
			sellFundDetail.setActionType(4);
			sellFundDetail.setAmount(sum);
			sellFundDetail.setProject(project);
			sellFundDetail.setProduct(product);
			sellFundDetail.setUser(seller);
			sellFundDetail.setTradeNo(no);
			sellFundDetail.setRemainingSum(seller.getFund() + sum);
			fundDetailService.addFundDetail(sellFundDetail);					
			seller.setFund(seller.getFund() + sum);
			userService.updateUser(seller);

			Integer supportCount = projectSupportService.countProjectSupport(
					projectId).intValue();
			
			project.setFundCurrent(project.getFundCurrent()+ fundDetail.getAmount());
			project.setSupportCount(supportCount);
			project.setProductAmount(count+project.getProductAmount());
			//project.setFundCurrent(fundCurrent);

			projectService.updateProject(project);
			map.put("success", "trade success");
			map.put("product", product);
			map.put("support", projectSupport);
			return new ResponseEntity(map,HttpStatus.CREATED);
		
	}

	// 根据project id 获取支持列表
	@RequestMapping(value = "/support/list",method=RequestMethod.GET)
	public ResponseEntity<HttpEntity> listFundDetailByProject(
			@RequestParam(value = "pid") int projectId,
			@RequestParam(value = "p", defaultValue = "1") int pageNo,
			@RequestParam(value = "s", defaultValue = "4") int pageSize,
			Model model) {

		Page<ProjectSupport> projectSupports = projectSupportService
				.findSupportsById(projectId, pageNo, pageSize);
		return new ResponseEntity(projectSupports, HttpStatus.OK);
	}

	// 根据user id 获取支持列表
	@RequestMapping(value = "/support/user/list",method=RequestMethod.GET)
	public ResponseEntity<HttpEntity> listProjectSupport(
			@RequestParam(value = "uid") int userId,
			@RequestParam(value = "p", defaultValue = "1") int pageNo,
			@RequestParam(value = "s", defaultValue = "4") int pageSize,
			@RequestParam(value = "start", required = false) Long start,
			@RequestParam(value = "end", required = false) Long end, Model model) {

		Page<ProjectSupport> projectSupports = projectSupportService
				.findSupportsByUser(userId, pageNo, pageSize, start, end);
		model.addAttribute(projectSupports);
		model.addAttribute(projectSupportService.sumMoney(userId));
		return new ResponseEntity(projectSupports, HttpStatus.OK);
	}
	
	//获取用户消费总额
	@RequestMapping(value = "/support/user/sum",method=RequestMethod.GET)
	public ResponseEntity<HttpEntity> listProjectSupport(
			@RequestParam(value = "uid") int userId,Model model) {

		model.addAttribute("sum",projectSupportService.sumMoney(userId));
		return new ResponseEntity(model, HttpStatus.OK);
	}

	// 添加反对项目
	@RequestMapping(value = "/unsupport/add", method = RequestMethod.POST)
	public ResponseEntity<HttpEntity> unsupprotProject(
			@Valid @RequestBody ProjectUnsupport projectUnsupport) {
		Map<String, Object> map = Maps.newHashMap();
		String msg="";
		if(projectUnsupportService.addUnsupport(projectUnsupport)){
			msg="success";
		}else{
			msg="fail";
		}
		map.put("msg",msg);
		return new ResponseEntity(map,HttpStatus.OK);
	}
	//获取项目反对数
	@RequestMapping(value="/unsupport/getcount",method=RequestMethod.GET)
	public ResponseEntity<HttpEntity> getUnsupportProjectCount(
			@RequestParam(value="pid",required=true) Integer projectId,
			@RequestParam(value="uid",required=false) Integer userId,
			Model  model){
		model.addAttribute("unSupportCount", projectUnsupportService.getUnSupportCount(projectId));
		if(userId!=null){
			model.addAttribute("approveUnsupport", projectSupportService.approveSupport(projectId, userId));
		}
		return new ResponseEntity(model, HttpStatus.OK);
	}
	
	//订单ProjectSupport选择送货地址
	@RequestMapping(value = "/support/sendto", method = RequestMethod.POST)
	public ResponseEntity<?> sendProductTo(@Valid ProjectSupport projectSupport,
										   @Valid SendTo sendTo) {
		
		SendTo oldSt = sendToService.getById(sendTo.getId());
		ProjectSupport oldPS = projectSupportService.getProjectSupport(projectSupport.getId());
		projectSupportService.update(oldPS);
		return new ResponseEntity(true, HttpStatus.OK);
	}
	
	//删除礼品
	@RequestMapping(value = "/support/present/del", method = RequestMethod.GET)
	public ResponseEntity<?> delPresent(@RequestParam(value = "pid")int pid) {
		presentService.del(pid);
		return new ResponseEntity(true, HttpStatus.OK);
	}
	
	//送礼
	@RequestMapping(value = "/support/present/send", method = RequestMethod.POST)
	public ResponseEntity<?> givePresent(@RequestParam(value = "phone")String phone,
										 @Valid ProjectSupport projectSupport) {
		
		User oldUser = userService.getUserByEmail(phone);
		Product product = productService.getProduct(projectSupport.getProduct().getId());
		User newUser = userService.getUser(projectSupport.getUser().getId());
		Project project = projectService.getProject(projectSupport.getProject().getId());
		//商品剩余数：amount；购买数量：count;需支付金额：sum;购买限额：limit
		Map map = new HashMap();
		//int amount = product.getRemaining()-projectSupport.getProductAmount();
		int count = projectSupport.getProductAmount();
		int sum = product.getPrice()*count;
		//int limit = product.getCaps()==null?0:product.getCaps();
		//送礼人id：userId;送礼人角色：role；支持项目id：projectId;商品id:projectId;送礼人对于项目历史购买数量：historyCount
		int userId = projectSupport.getUser().getId();
		String role = null;//userService.getUser(userId).getRoles();
		int projectId = projectSupport.getProject().getId();
		int productId = projectSupport.getProduct().getId();
		int historyCount = projectSupportService.sumProductAmount(projectId, userId,productId).intValue();
		int newCount = count + historyCount; //本次加上历史一共购买的数量
		String permissions = product.getPermissions();
		//用户不存在时创建用户，并将初始密码发送出去
		if( oldUser == null ) {
			User user = new User();
			user.setStatus(UserStatus.locked.getCode());
			//user.setRoles("user");
			user.setFund(0);
			user.setLoginName(phone);
			user.setName(phone);
			String passward = String.valueOf(Math.random()).substring(2,8);
			user.setPlainPassword(passward);
			userService.registUser(user);
			FundDetail fundDetial = fundDetailService.getFundDetail(newUser.getId());
			if(fundDetial!=null){	
				if(newUser.getFund()<sum+fundDetial.getAmount()){
					log.debug("user's fund is:" + newUser.getFund());
					map.put("error", "Lack of Funds!");
					map.put("product", product);
					return new ResponseEntity(map, HttpStatus.BAD_REQUEST);
				}/*else if (product.getRemaining()==0||product.getRemaining()<projectSupport.getProductAmount()) {
				log.debug("Remaining deficiencies!");
				map.put("error", "Remaining deficiencies ");
				map.put("product", product);
				return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
			}else */
			}else{	
				if(newUser.getFund()<sum){
					log.debug("user's fund is:" + newUser.getFund());
					map.put("error", "Lack of Funds!");
					map.put("product", product);
					return new ResponseEntity(map, HttpStatus.BAD_REQUEST);
				}
			}
			if (project.getStatus()!=5) {
				log.debug("Project's status is fail!");
				map.put("error", "Project's status is fail ");
				map.put("product", product);
				return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
			}else {
				//判断是否有权限，及购买数量是否大于上限
				if(!permissions.equals("yes")){
					map.put("error", "No buy permissions");
					return new ResponseEntity(map,HttpStatus.FORBIDDEN);
				}
		/*		if ( role.equals("user")&&newCount > limit ) {
					map.put("error", "Purchase quantity is greater than the limit on the number!");
					return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
				}*/
				//更新商品销售数
				product.setAmmount(count+product.getAmmount());
				productService.update(product);
				//更新雅米宝余额
				User toUser = userService.getUser(projectSupport.getUser().getId());
				toUser.setFund(toUser.getFund() - sum);
				userService.updateUser(toUser);
				//更新项目支持记录
				String no = OrderNoGenerator.generator("NO");
				projectSupport.setFundCode(no);
				projectSupport.setStatus(101);
				projectSupport.setUser(newUser);
				projectSupport.setProduct(product);
				projectSupport.setIsBuy(1);
				projectSupportService.add(projectSupport);
				
				//增加送礼记录
				Present present = new Present();
				present.setStatus(0);
				present.setSupport(projectSupport);
				present.setToPhone(phone);
				presentService.save(present);
				
				//更新雅米宝收支情况信息
				FundDetail fundDetail = new FundDetail();
				fundDetail.setActionType(0);
				fundDetail.setAmount(sum);
				fundDetail.setProject(projectSupport.getProject());
				fundDetail.setUser(projectSupport.getUser());
				fundDetail.setProduct(product);
				fundDetail.setTradeNo(no);
				fundDetail.setRemainingSum(toUser.getFund() - sum);
				fundDetailService.addFundDetail(fundDetail);
				
				//更新卖家的余额
				User seller =project.getInstitution().getUser();
				FundDetail sellFundDetail = new FundDetail();
				sellFundDetail.setActionType(4);
				sellFundDetail.setAmount(sum);
				sellFundDetail.setProject(project);
				sellFundDetail.setProduct(product);
				sellFundDetail.setUser(seller);
				sellFundDetail.setTradeNo(no);
				sellFundDetail.setRemainingSum(seller.getFund() + sum);
				fundDetailService.addFundDetail(sellFundDetail);					
				seller.setFund(seller.getFund() + sum);
				userService.updateUser(seller);				
				
				
				
				//更新项目筹款
				project.setFundCurrent(project.getFundCurrent()+sum);
				Integer supportCount = projectSupportService.countProjectSupport(projectSupport.getProject().getId()).intValue();
				project.setSupportCount(supportCount);
				project.setProductAmount(count+project.getProductAmount());
				projectService.updateProject(project);
				//发送短信
				oldUser = user;
				presentService.addUser(oldUser,projectSupport);
				return new ResponseEntity(true, HttpStatus.OK);
			}
			
		}else{
			
			FundDetail fundDetial = fundDetailService.getFundDetail(newUser.getId());
			if(fundDetial!=null){	
				if(newUser.getFund()<sum+fundDetial.getAmount()){
					log.debug("user's fund is:" + newUser.getFund());
					map.put("error", "Lack of Funds!");
					map.put("product", product);
					return new ResponseEntity(map, HttpStatus.BAD_REQUEST);
				}/*else if (product.getRemaining()==0||product.getRemaining()<projectSupport.getProductAmount()) {
				log.debug("Remaining deficiencies!");
				map.put("error", "Remaining deficiencies ");
				map.put("product", product);
				return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
			}else */
			}else{	
				if(newUser.getFund()<sum){
					log.debug("user's fund is:" + newUser.getFund());
					map.put("error", "Lack of Funds!");
					map.put("product", product);
					return new ResponseEntity(map, HttpStatus.BAD_REQUEST);
				}
			}
			if (project.getStatus()!=5) {
				log.debug("Project's status is fail!");
				map.put("error", "Project's status is fail ");
				map.put("product", product);
				return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
			}else {
				//判断是否有权限，及购买数量是否大于上限
				if(!permissions.equals("yes")){
					map.put("error", "No buy permissions");
					return new ResponseEntity(map,HttpStatus.FORBIDDEN);
				}
			/*	if ( role.equals("user")&&newCount > limit) {
					map.put("error", "Purchase quantity is greater than the limit on the number or no permission to buy!");
					return new ResponseEntity(map,HttpStatus.EXPECTATION_FAILED);
				}*/
				//更新商品剩余数
				//product.setRemaining(amount);
				product.setAmmount(count+product.getAmmount());
				productService.update(product);
				//更新雅米宝余额
				User toUser = userService.getUser(projectSupport.getUser().getId());
				toUser.setFund(toUser.getFund() - sum);
				userService.updateUser(toUser);
				//更新项目支持记录
				String no = OrderNoGenerator.generator("NO");
				projectSupport.setFundCode(no);
				projectSupport.setStatus(101);
				projectSupport.setUser(newUser); 
				projectSupport.setProduct(product);
				projectSupport.setIsBuy(1);
				projectSupportService.add(projectSupport);
				
				//增加送礼记录
				Present present = new Present();
				present.setStatus(0);
				present.setSupport(projectSupport);
				present.setToPhone(phone);
				presentService.save(present);
				
				//更新雅米宝收支情况信息
				FundDetail fundDetail = new FundDetail();
				fundDetail.setActionType(0);
				fundDetail.setAmount(sum);
				fundDetail.setProject(projectSupport.getProject());
				fundDetail.setUser(projectSupport.getUser());
				fundDetail.setProduct(product);
				fundDetail.setTradeNo(no);
				fundDetail.setRemainingSum(toUser.getFund() - sum);
				fundDetailService.addFundDetail(fundDetail);
				
				//更新卖家的余额
				User seller =project.getInstitution().getUser();	
				FundDetail sellFundDetail = new FundDetail();
				sellFundDetail.setActionType(4);
				sellFundDetail.setAmount(sum);
				sellFundDetail.setProject(project);
				sellFundDetail.setProduct(product);
				sellFundDetail.setUser(seller);
				sellFundDetail.setTradeNo(no);
				sellFundDetail.setRemainingSum(seller.getFund() + sum);
				fundDetailService.addFundDetail(sellFundDetail);					
				seller.setFund(seller.getFund() + sum);
				userService.updateUser(seller);				
			
				
				//更新项目筹款
				project.setFundCurrent(project.getFundCurrent()+sum);
				project.setSupportCount(project.getSupportCount()+1);
				project.setProductAmount(count+project.getProductAmount());
				projectService.updateProject(project);
				//发送短信
				presentService.sendMail(projectSupport, oldUser,newUser);
				return new ResponseEntity(true, HttpStatus.OK);
			}
			
		}
	}
	
	//收礼
	@RequestMapping(value = "/support/present/receive", method = RequestMethod.POST)
	public ResponseEntity<?> receivePresent(@Valid @RequestBody SendTo sendto,
											@Valid @RequestBody Present present) {
		
		present.setStatus(1);
		presentService.update(present);
		ProjectSupport ps = projectSupportService.getProjectSupport(present.getId());
		projectSupportService.update(ps);
		return new ResponseEntity(true, HttpStatus.OK);
	}
	
	
	//根据手机号列出所有收到礼品
	@RequestMapping(value = "/support/present/list", method = RequestMethod.GET)
	public ResponseEntity<?> presentList(@RequestParam(value = "uid", required = true)int uid,
			@RequestParam(value = "p", defaultValue = "1") int pageNo,
			@RequestParam(value = "s", defaultValue = "4") int pageSize) {
		
		User user = userService.getUser(uid);
		Page<Present> page = presentService.findAllByPhone(user.getLoginName(), pageNo, pageSize);
		for (int i = 0; i < page.getResult().size(); i++) {
			Project project = projectService.getProject(page.getResult().get(i).getSupport().getProject().getId());
			Integer supportCount = projectSupportService.countProjectSupport(project.getId()).intValue();
			project.setSupportCount(supportCount);
			projectService.updateProject(project);
			Present present = presentService.getPresent(page.getResult().get(i).getId());
			present.setStatus(1);
			presentService.update(present);
		}
		Page<Present> newPage = presentService.findAllByPhone(user.getLoginName(), pageNo, pageSize);
		return new ResponseEntity(newPage, HttpStatus.OK);
	}
	
	@RequestMapping(value = "/support/present/detail", method = RequestMethod.GET)
	public ResponseEntity<?> presentGet(@RequestParam(value = "pid", required = true)Integer presentId) {
		
		Present present = presentService.findOne(presentId);
		return new ResponseEntity(present, HttpStatus.OK);
	}
	
	//根据状态查询礼品
	@RequestMapping(value = "/support/present/search/{status}", method = RequestMethod.GET)
	public ResponseEntity<?> presentSearch(@RequestParam(value = "loginName", required = true)String loginName,
										   @PathVariable("status")String status,
											@RequestParam(value = "p", defaultValue = "1") int pageNo,
											@RequestParam(value = "s", defaultValue = "4") int pageSize) {

		if( status.equals("received")) {
			Page<Present> page = presentService.findPrsentByStatus(loginName, 1, pageNo, pageSize);
			return new ResponseEntity(page, HttpStatus.OK);
		}
		else if ( status.equals("unreceived")) {

			Page<Present> page = presentService.findPrsentByStatus(loginName, 0, pageNo, pageSize);
			return new ResponseEntity(page, HttpStatus.OK);
		}
		else {
			
			return new ResponseEntity(false, HttpStatus.OK);		
		}
	}
}

